/*
 * mail_mgr.h
 *
 *  Created on: Jan 20, 2014
 *      Author: killerg
 */

#ifndef MAIL_MGR_H_
#define MAIL_MGR_H_

#include "share/json/json.h"
#include "share/patterns.h"
#include "share/cs_msg.pb.h"
#include "share/db_mgr.h"

struct mail_t {
    int32_t mailid = -1;
    int64_t sender = -1;
    int32_t date = 0;
    string content;
    int32_t rewardid = -1;
    float rewardpct = 0.0f;
    bool readed = false;
    bool rewarded = false;
    int32_t type = cs::EMT_Person;
};

struct mailbox_t {
    int64_t boxid = -1;
    string account;
    string playername;
    ptr_map<int32_t, mail_t*> system;
    ptr_map<int32_t, mail_t*> person;

    int new_system = 0;
    int new_person = 0;
    int last_system = -1;
    int last_person = -1;
    int valid_mailid = 0;

    bool player_online = false;
    int32_t chg_stamp = 0;
    int32_t sav_stamp = 0;
    enum {
        Unchged = 0,
        Saving = 1,
        Queuing = 2,
    } state = Unchged;

    void init(const Json::Value &json);
    void save(Json::Value &json);
    void destroy();

    mail_t* get_mail(int32_t mailid) {
        mail_t* mail = system.get(mailid);
        if (NULL == mail)
            mail = person.get(mailid);

        return mail;
    }
    void post_save(function<void(bool)> cb = NULL);
    void add_queue(bool chg);
};

typedef function<void(db_error_t, mailbox_t*)> mailbox_load_cb_t;
typedef function<void(db_error_t)> mailbox_create_cb_t;


struct mailmgr_t {
    ptr_map<int64_t, mailbox_t*, unordered_map<int64_t, mailbox_t*> > boxes;
    unordered_map<int64_t, list<mailbox_load_cb_t> > loading;
    unordered_map<int64_t, mailbox_create_cb_t > creating;

    void box_load(int64_t boxid, mailbox_load_cb_t cb);
    void box_create(int64_t boxid, const string &account, const string &playername, mailbox_create_cb_t cb);

    void send_system(int64_t boxid, cs::EMailType type, const string &content, int32_t rewardid, double rewardpct = 1.0f, function<void(bool)> cb = NULL);
    void send_person(int64_t boxid, int64_t sender, const string &content, function<void(bool)> cb);

    bool init();
    void destroy();
    void update();

    void update_save_queue(int num = -1);
    queue<mailbox_t*> save_queue;
    int saving = 0;
};

#endif /* MAIL_MGR_H_ */
